package ua.com.softway.db.date;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

import ua.com.softway.date.Date;

public class DateType implements UserType {

    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }
    
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }
    
    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        if (value == null) return null;
        
        Date d = (Date) value;
        
        return new Date(d.getYear(), d.getMonth(), d.getDay());
    }

    @Override
    public boolean equals(Object left, Object right) throws HibernateException {
        if (left == null)
            return right == null;

        return left.equals(right);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        if (x == null) return 0;
        return x.hashCode();
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
        java.util.Date d = rs.getDate(names[0]);
        
        if (d == null) return null;
        
        return Date.fromJavaDate(d);
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        if (value == null)
            st.setDate(index, null);
        else {
            java.sql.Date d = new java.sql.Date(((Date) value).toJavaDate().getTime());
            
            st.setDate(index, d);
        }
    }

    @Override
    public Class<?> returnedClass() {
        return Date.class;
    }

    @Override
    public int[] sqlTypes() {
        return new int[] { Types.DATE };
    }

}
